/**
 * @brief XML格式的配置文件
 * @version 1.0
 * @author 宋炜
 * @date 
 */

#pragma once

#include <string>
#include <memory>
#include <libxml/parser.h>

#include "details/confdom.hpp"
/**
 * 文档结构校验模块
 */
class confFileVerify
{
public:
	/**
	 * @brief 校验文件
	 * @param xml[ I ], xml文件路径
	 * @param sch[ I ], xml scheme 文件路径
	 */
	static bool verify( const std::string& xml , const std::string& sch );
};

/// 文档解析器
class confFileReader
{
public:
	using dom_t = std::shared_ptr< confDOM >;
	using domStack_t = std::stack< std::shared_ptr< dm::composite< stDOMItem > > >;
private:
	std::shared_ptr< xmlDoc >    pt_file__;
	std::shared_ptr< confDOM >   pt_dom__;
	domStack_t                   pt_stack__;
	
private:
	/**
	 * @brief 将libxml2的结构转换为实际需要使用DOM结构
	 * @return 成功操作返回true，否则返回false
	 */
	bool xml2dom__();
	/**
	 * @brief 加XML节点转换成DOM节点
	 * @param
	 * @return 成功操作返回节点指针否则返回没有初始化的智能指针
	 */
	std::shared_ptr< composite< stDOMItem > >
	todom__( std::shared_ptr< composite< stDOMItem > > , xmlNodePtr node );
	/**
	 * @brief 检查节点是否符合标准
	 * @param node[ I ] , xml节点
	 * @return 合法返回true,否则返回false
	 */
	bool check_node__( xmlNodePtr node );
	bool check_data_node__( xmlNodePtr node );
	bool check_array_node__( xmlNodePtr node );
	bool check_group_node__( xmlNodePtr node );
	bool check_enum_node__( xmlNodePtr node );
	bool check_root_node__( xmlNodePtr node );
	bool check_array_item__( xmlNodePtr node );
	bool check_enum_item__( xmlNodePtr node );

	bool check_type_name__( const char * type );
	
	/**
	 * @brief 转化数据，将node内容转化为DOM节点内容
	 * @param type[ I ] 节点类型,对应节点的type属性
	 * @param name[ I ] 变量名称，是节点名称主要是DATA, GROUP，ARRAY,ENUM
	 * @param node[ I ] XML节点
	 * @return 返回转换结果
	 */
	stDOMItem convert_data__( const std::string& type , const std::string& name , xmlNodePtr node );
	/**
	 * @brief
	 * @param name[ I ], 变量名称，对应与节点的name属性
	 */
	stDOMItem convert_data_node__( const std::string& type , const std::string& name , xmlNodePtr node );
	stDOMItem convert_array_node__( const std::string& type , const std::string& name , xmlNodePtr node );
	stDOMItem convert_group_node__( const std::string& type , const std::string& name , xmlNodePtr node );
	stDOMItem convert_enum_node__( const std::string& type , const std::string& name , xmlNodePtr node );
	stDOMItem convert_confFile_node__( const std::string& type , const std::string& name , xmlNodePtr node );
	stDOMItem convert_array_item_node__( const std::string& type , const std::string& name , xmlNodePtr node );
	stDOMItem convert_enum_e_node__( const std::string& type , const std::string& name , xmlNodePtr node );
	
public:
	confFile( const std::string& file );
	~confFile();

	bool load( const std::string& file );
	/**
	 * @brief 返回DOM对象
	 */
	dom_t dom();
};

/// 文档生成器。
class confFileWriter
{
public:

private:

private:

public:
	confFileWriter();
	confFileWriter( const std::string& file , const std::shared_ptr<confDOM> &dom );
	~confFileWriter();

	bool save( const std::string& file );
	bool save( const std::string& file , const std::shared_ptr< confDOM >& dom );
};
